Skip to content

Conversation

@grdsdev
Copy link
Contributor

@grdsdev grdsdev commented Dec 5, 2025

🔍 Description

This PR implements the Realtime V2 serializer, porting features from supabase-js PRs #1829 and #1894.

What changed?

  • Added V2 Serializer (version 2.0.0) with binary payload support
  • New message types: user broadcast and user broadcast push
  • Metadata support for user broadcast push messages with configurable allowed keys
  • Backward compatible: V1 (1.0.0) remains the default

Why was this change needed?

  • Binary payload support enables more efficient data transfer for real-time applications
  • Reduces JSON encoding overhead on the server side
  • Provides foundation for future real-time features requiring binary data
  • Maintains compatibility with existing implementations

📝 Implementation Details

New Components

  1. RealtimeBinaryEncoder: Encodes messages to binary format

    • Supports binary and JSON payloads
    • Handles user broadcast push with optional metadata
    • Validates field lengths (max 255 bytes per field)
  2. RealtimeBinaryDecoder: Decodes binary messages from server

    • Handles push, reply, broadcast, and user broadcast message types
    • Supports both binary and JSON payload encoding
    • Extracts metadata when present
  3. RealtimeBinaryPayload: Helper utilities for working with binary data

    • Create binary payload markers
    • Check if payload is binary
    • Extract binary data from payloads
  4. RealtimeClientOptions: Extended with serializer configuration

    • serializerVersion: Choose between "1.0.0" (default) and "2.0.0"
    • allowedMetadataKeys: Configure which keys are included in metadata

Design Decisions

  • Binary data is stored as base64-encoded strings within AnyJSON to avoid modifying the general-purpose AnyJSON enum
  • Used protocol-based design with separate encoder/decoder classes for clean separation of concerns
  • All classes are marked as Sendable for Swift 6 compatibility
  • Tests mirror the supabase-js test structure for consistency

🧪 Testing

Added comprehensive test suite (RealtimeSerializerTests.swift) with 16 tests covering:

  • Binary push encoding/decoding
  • User broadcast with JSON and binary payloads
  • Metadata handling and filtering
  • Field length validation
  • Round-trip encoding/decoding
  • Binary payload helper utilities

All 146 existing Realtime tests continue to pass.

📸 Usage Example

// Enable V2 serializer when creating client
let client = RealtimeClientV2(
  url: realtimeURL,
  options: RealtimeClientOptions(
    headers: ["apikey": apiKey],
    serializerVersion: "2.0.0",
    allowedMetadataKeys: ["custom_field"]  // Optional
  )
)

// Send binary data
let binaryData = Data([0x01, 0x02, 0x03])
let message = RealtimeMessageV2(
  joinRef: "ref1",
  ref: "ref2",
  topic: "my-topic",
  event: "broadcast",
  payload: [
    "event": "my-event",
    "payload": RealtimeBinaryPayload.binary(binaryData)
  ]
)

🔄 Breaking changes

  • This PR contains no breaking changes

The V2 serializer is opt-in via configuration, and V1 remains the default.

📋 Checklist

  • I have read the Contributing Guidelines
  • My PR title follows the conventional commit format: <type>(<scope>): <description>
  • I have run make format to ensure consistent code formatting
  • I have added tests for new functionality
  • All existing tests pass

📝 Additional notes

This implementation closely follows the TypeScript version from supabase-js to ensure consistency across SDKs. The serializer version is included in the WebSocket URL query string (vsn parameter) to allow the server to handle both protocols.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

This implements the Realtime V2 serializer based on supabase-js PRs #1829 and #1894.

Key features:
- Binary payload support for user messages
- Two new message types: user broadcast and user broadcast push
- Optional metadata support for user broadcast push messages
- Reduced JSON encoding overhead on the server side
- Backward compatible with V1 (1.0.0) as default

Changes:
- Added RealtimeBinaryEncoder and RealtimeBinaryDecoder classes
- Added RealtimeSerializer protocol for future extensibility
- Updated RealtimeClientOptions to support serializer version selection
- Updated RealtimeClientV2 to use binary serializer when v2.0.0 is selected
- Added RealtimeBinaryPayload helper for working with binary data
- Comprehensive test suite with 16 tests covering encoding/decoding scenarios

References:
- supabase/supabase-js#1829
- supabase/supabase-js#1894

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@grdsdev grdsdev marked this pull request as draft December 5, 2025 10:02
This commit refactors the binary serializer implementation to introduce
RealtimeMessageV3, which provides proper type distinction between JSON
and binary payloads. This approach avoids breaking changes by keeping
RealtimeMessageV2 intact while allowing gradual migration to the new type.

Key changes:
- Add RealtimeMessageV3 with RealtimePayload enum (json/binary)
- Update RealtimeBinaryEncoder to work with V3 messages
- Update RealtimeBinaryDecoder to return V3 messages
- Add conversion methods between V2 and V3
- Update RealtimeClientV2 with pushV3() method
- Update tests to use V3 messages
- Add 4 new V2/V3 conversion tests
- Fix MockRealtimeClient to implement pushV3()
- Fix Swift 6 warnings with 'any Encoder' and 'any Decoder'

The V2 serializer now properly encodes/decodes both JSON and binary
payloads with support for metadata in user broadcast messages.

Related to supabase-js PRs:
- #1829: Implement Realtime V2 Serializer
- #1894: Add metadata to realtime user broadcast push

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants